﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using System.ComponentModel;

namespace MVC4WPF.Automation.VisualStudio.Dialog
{
    /// <summary>
    /// Interaction logic for ViewDialog.xaml
    /// </summary>
    public partial class ViewDialog : Window, IViewDialog, INotifyPropertyChanged
    {
        #region Fields

        #endregion

        #region Constructor

        /// <summary>
        /// Public constructor for the ViewDialog class.
        /// </summary>
        public ViewDialog()
        {
            this.InitializeComponent();
        }

        #endregion

        #region Event Handlers

        /// <summary>
        /// The Select Button click handler
        /// </summary>
        /// <param name="sender">Sender of the event</param>
        /// <param name="e">Argument provided by the sender</param>
        private void ButtonSelect_Click(object sender, System.Windows.RoutedEventArgs e)
        {
            //Letting external processing occur.
            OnSelected();

            //If a view contract has not been selected
            if (ViewPropertyBag.SelectedContract == null)
            {
                //Prompt the user to select a view contract
                MessageBox.Show("Please select a view contract to continue.", "View Contract Not Selected", MessageBoxButton.OK, MessageBoxImage.Asterisk);
                return;
            }
            //everything is good, return a success condition and close the dialog window
            this.DialogResult = true;
            this.Close();
        }

        /// <summary>
        /// The Cancel Button click handler
        /// </summary>
        /// <param name="sender">The sender of the event</param>
        /// <param name="e">Argument provided by the sender</param>
        private void ButtonCancel_Click(object sender, System.Windows.RoutedEventArgs e)
        {
            //cancel was clicked, return the default cancel condition and close the dialog window
            this.Close();
        }

        #endregion

        #region IDialogBase Members

        private EventHandler<EventArgs> _selectedHandler;
        private object _selectedHandlerLocker = new object();

        /// <summary>
        /// Implicit implementation of the event that an item has been selected from the dialog.
        /// </summary>
        event EventHandler<EventArgs> MVC4WPF.Automation.Dialog.IDialogBase.ItemSelected
        {
            add
            {
                lock (_selectedHandler)
                {
                    _selectedHandler += value;
                }
            }
            remove
            {
                lock (_selectedHandler)
                {
                    _selectedHandler -= value;
                }
            }
        }

        /// <summary>
        /// Implicit implementation of the dialog base ShowDialog method. Shows the dialog.
        /// </summary>
        /// <returns></returns>
        bool MVC4WPF.Automation.Dialog.IDialogBase.ShowDialog()
        {
            //show the dialog
            bool? result = this.ShowDialog();

            //return false by default
            return result.GetValueOrDefault(false);
        }

        #endregion

        #region Helper Methods

        /// <summary>
        /// Raised the on selected event so that subscribers can do any processing they wish
        /// </summary>
        private void OnSelected()
        {
            if (_selectedHandler != null)
            {
                _selectedHandler.Invoke(this, new EventArgs());
            }
        }
        #endregion

        #region Implementation of INotifyPropertyChanged and INotifyPropertyChanging

        #region Implementation of event - PropertyChanged

        /// <summary>
        /// Local variable that is the event handler for the event 'PropertyChanged'.
        /// </summary>
        private System.ComponentModel.PropertyChangedEventHandler _propertyChanged;

        /// <summary>
        /// Local variable that is the lock object for the event 'PropertyChanged', this is included for thread safety.
        /// </summary>
        private object _propertyChangedEventLock = new object();

        /// <summary>
        /// Event that gets fired every time an a property has been changed on the controller.
        /// </summary>
        public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged
        {
            add
            {
                lock (_propertyChangedEventLock)
                {
                    _propertyChanged += value;
                }
            }

            remove
            {
                lock (_propertyChangedEventLock)
                {
                    _propertyChanged -= value;
                }
            }
        }

        /// <summary>
        /// Raises the property changed event synchronously. The event will only be raised if there are subscribers to the event.
        /// </summary>
        /// <param name="propertyName">The name of the property that changed</param>
        protected virtual void OnPropertyChanged(string propertyName)
        {
            if (this._propertyChanged != null)
            {
                this._propertyChanged.Invoke(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName));
            }
        }

        /// <summary>
        /// Helper method that is to be called by IDisposable to release the event 'PropertyChanged' and supporting resources.
        /// </summary>
        private void CleanupPropertyChangedEvent()
        {
            try
            {
                _propertyChanged = null;

                _propertyChangedEventLock = null;
            }

            catch
            {
            }
        }

        #endregion

        #region Implementation of event - PropertyChanging

        /// <summary>
        /// Local variable that is the event handler for the event 'PropertyChanging'.
        /// </summary>
        private System.ComponentModel.PropertyChangingEventHandler _propertyChanging;

        /// <summary>
        /// Local variable that is the lock object for the event 'PropertyChanging', this is included for thread safety.
        /// </summary>
        private object _propertyChangingEventLock = new object();

        /// <summary>
        /// Event that gets fired every time a property is about to get changed in the controller.
        /// </summary>
        public event System.ComponentModel.PropertyChangingEventHandler PropertyChanging
        {
            add
            {
                lock (_propertyChangingEventLock)
                {
                    _propertyChanging += value;
                }
            }

            remove
            {
                lock (_propertyChangingEventLock)
                {
                    _propertyChanging -= value;
                }
            }
        }

        /// <summary>
        /// Raises the property changing event synchronously. The event will only be raised if there are subscribers to the event.
        /// </summary>
        /// <param name="propertyName">The name of the property that is changing</param>
        protected virtual void OnPropertyChanging(string propertyName)
        {
            if (this._propertyChanging != null)
            {
                this._propertyChanging.Invoke(this, new System.ComponentModel.PropertyChangingEventArgs(propertyName));
            }
        }

        /// <summary>
        /// Helper method that is to be called by IDisposable to release the event 'PropertyChanging' and supporting resources.
        /// </summary>
        private void CleanupPropertyChangingEvent()
        {
            try
            {
                _propertyChanging = null;

                _propertyChangingEventLock = null;
            }
            catch
            {
            }
        }

        #endregion

        #endregion

        #region IViewPropertyBag<ViewDialogPropertyBag> Members

        #region Property - ViewPropertyBag
        //Local variable for property ViewPropertyBag
        private ViewDialogPropertyBag _viewPropertyBag = new ViewDialogPropertyBag();

        /// <summary>
        /// The property bag for the view dialog
        /// </summary>
        public ViewDialogPropertyBag ViewPropertyBag
        {
            get
            {
                return _viewPropertyBag;
            }

            set
            {
                OnPropertyChanging("ViewPropertyBag");

                _viewPropertyBag = value;

                OnPropertyChanged("ViewPropertyBag");
            }
        }
        #endregion Property - ViewPropertyBag

        #endregion
    }
}